from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django import forms
# from .models import StoreRawOrderModel, StoreRawDetailModel,SellRawOrderModel,SellRawDetailModel
from django.shortcuts import render
from store import models
from base import models as baseModels
from django.urls import reverse  # 导入reverse用于生成URL
from django.shortcuts import redirect

from django.utils.html import format_html
from django.core.exceptions import ValidationError

from django import forms
from .admin_utils import log_model_changes

from base.admin import DefineImportExportModelAdmin
from decimal import Decimal, ROUND_HALF_UP
from django.db.models import Sum, F, ExpressionWrapper, DecimalField
from django.db.models.functions import Coalesce
class StoreRawDetailForm(forms.ModelForm):
    # 新增金额字段（不存入数据库，仅用于计算）
    amount = forms.DecimalField(
        label="不含税金额",
        required=False,
        max_digits=12,
        decimal_places=2,
        widget=forms.NumberInput(attrs={
            'class': 'amount-input',  # 用于JS选择
            'step': '0.01'  # 支持小数输入
        })
    )
    class Meta:
        model = models.StoreRawDetailModel
        fields = ('raw', 'store_num','unit')

class StoreRawOrderFileForm(forms.ModelForm):
    class Meta:
        model = models.StoreRawOrderFileModel
        fields = ('id', 'store_order','file')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreRawFileInline(admin.TabularInline):
    model = models.StoreRawOrderFileModel
    form = StoreRawOrderFileForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    classes = ['collapse'] # 添加collapse类，这是Django Admin内置的
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "附件"
    verbose_name_plural = "附件"

    # 明细表单字段配置
    fields = ('file',)


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ()  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题

# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreRawDetailInline(admin.TabularInline):
    model = models.StoreRawDetailModel
    form = StoreRawDetailForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    template = 'store/custom_tabular.html'  # 加载自定义模板
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "入库明细"
    verbose_name_plural = "入库明细"

    # 明细表单字段配置
    fields = ('raw', 'store_num', 'unit', 'price', 'tax','amount', 'batch_number', 'location')


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw','unit')  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题
    def get_queryset(self, request):
        """
        重写查询集：只返回当前入库单关联的、且parent字段为空的明细数据
        - 父类的get_queryset已自动过滤出当前入库单（store_order=当前主表对象）的数据
        - 额外添加parent__isnull=True，过滤掉parent有数值的记录
        """
        qs = super().get_queryset(request)
        # 核心过滤条件：parent为空（parent__isnull=True）
        return qs.filter(parent__isnull=True)


class StoreRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.StoreRawOrderModel

        fields=['orderId', 'date','type','supplier']



@admin.register(models.StoreRawOrderModel)
class StoreRawOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = StoreRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_store_num','supplier_name','type','invoice', 'create_at','view_details_link')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId','supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StoreRawDetailInline,StoreRawFileInline]

    # 表单字段分组
    fieldsets = (
        ('入库单基本信息', {
            'fields': ('orderId', 'date','type','invoice','supplier','remark'),
            'description': '请输入入库单号和入库日期'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request,object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """



        # parms=request.GET
        parms ={
            'orderId':request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'type': request.POST.get('type'),
            'invoice': request.POST.get('invoice'),
            'supplier': request.POST.get('supplier'),

        }
        try:
            parms['supplier_name']=baseModels.SupplierRawModel.objects.filter(pk=request.POST.get('supplier',1)).first().name
        except:
            parms['supplier_name'] = ''
        _fileds=[]
        details_counts=request.POST.get('storerawdetailmodel_set-TOTAL_FORMS',0)

        for i in range(int(details_counts)):
            raw=baseModels.RawModel.objects.filter(pk=request.POST.get(f'storerawdetailmodel_set-{i}-raw')).first(),
            unit = baseModels.UnitModel.objects.filter(pk=request.POST.get(f'storerawdetailmodel_set-{i}-unit')).first(),
            _fileds.append({
                'id':request.POST.get(f'storerawdetailmodel_set-{i}-id'),
                'store_order': request.POST.get(f'storerawdetailmodel_set-{i}-store_order'),
                'name':raw[0].name,
                'gui_ge': raw[0].gui_ge,
                'code': raw[0].code,
                'chan_di': raw[0].chan_di,
                'remark': raw[0].remark,
                'standard': str(raw[0].standard.name),
                'storage_condition': raw[0].storage_condition,

                'store_num': request.POST.get(f'storerawdetailmodel_set-{i}-store_num'),
                'unit': unit[0].unit,
                'price': request.POST.get(f'storerawdetailmodel_set-{i}-price'),
                'tax': request.POST.get(f'storerawdetailmodel_set-{i}-tax'),
                'amount': request.POST.get(f'storerawdetailmodel_set-{i}-amount'),
                'batch_number': request.POST.get(f'storerawdetailmodel_set-{i}-batch_number'),
                'location': request.POST.get(f'storerawdetailmodel_set-{i}-location'),
            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
             'model': code,
            'parms':parms,
            'report_type':'0',
            'fileds':_fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storerawdetailmodel_set.filter(parent__isnull=True).count()

    detail_count.short_description = "明细数量"  # 列标题
    def supplier_name(self,obj):
        return obj.supplier.name

    supplier_name.short_description = "供应商名"  # 列标题
    # 自定义列表字段：计算总入库数量
    def total_store_num(self, obj):
        from django.db.models import Sum
        total = obj.storerawdetailmodel_set.filter(parent__isnull=True).aggregate(
            total=Sum('store_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_store_num.short_description = "总入库数量"

    # 自定义字段：生成跳转链接（查看明细详情）
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)
        # 使用外键字段名+_id 作为筛选参数
        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/admin/store/storerawdetailmodel/?store_order__id={}&parent__isnull=True" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )

    view_details_link.short_description = "操作"  # 表头名称




@admin.register(models.StoreRawDetailModel)
class StoreRawDetailModelAdmin(DefineImportExportModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'store_order_link', 'raw','batch_number', 'store_num','unit','price','amount','tax','tax_inclusive_amount','tax_amount','invoice','remaining_num', 'store_order_supplier_name', 'raw_standard', 'create_at','view_details_link','location','get_type')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'store_order__orderId',  # 关联入库单号
        'raw__name', 'raw__code'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__standard',  # 按执行标准筛选
        'raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('store_order', 'raw','unit')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def store_order_link(self, obj):
        #通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storerawordermodel_change', args=[obj.store_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.store_order.orderId  # 显示入库单号
        )

    store_order_link.short_description = "入库单号"
    store_order_link.allow_tags = True  # 允许HTML渲染
    def amount(self, obj):
        result=obj.store_num * obj.price
        return result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
    amount.short_description = "金额"

    def tax_inclusive_amount(self, obj):
        result = obj.store_num * obj.price * (1+obj.tax *  Decimal('0.01'))
        return  result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)

    tax_inclusive_amount.short_description = "含税金额"
    def store_order_supplier_name(self, obj):
        return obj.store_order.supplier.name

    store_order_supplier_name.short_description = "供应商"
    def invoice(self,obj):
        TYPE_CHOICES = {
            '1':'没有发票',
            '0':'有发票'
        }

        return TYPE_CHOICES.get(obj.store_order.invoice,'发票异常')

    invoice.short_description = "发票"
    def tax_amount(self, obj):
        result = obj.store_num * obj.price * obj.tax * Decimal('0.01')
        return result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
    tax_amount.short_description = "税额"
    # 自定义字段：生成跳转链接（查看明细详情）
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)
        # 使用外键字段名+_id 作为筛选参数
        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/search/store/storerawdetailmodel/subledger/?pk={}" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )


    view_details_link.short_description = "明细账"
    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 自定义列表字段：显示原料的入库类型
    def get_type(self, obj):
        if obj.parent:
            return '调拨'
        elif obj.store_order.type=='1':
            return '入库单'
        else:
            return '期初入库单'

    get_type.short_description = "类型"
    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    # 动态控制列表显示字段（无权限时移除 view_details_link）
    def get_list_display(self, request):
        # 获取默认的列表字段（原 list_display）
        default_list_display = list(self.list_display)  # 原 list_display 是元组，转列表便于修改

        # 检查权限：无权限则移除 "view_details_link" 字段
        if not request.user.has_perm("store.view_subledger_storerawdetailmodel"):
            if "view_details_link" in default_list_display:
                default_list_display.remove("view_details_link")

        return default_list_display


class TransferRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.TransferRawDetailModel
        fields = ('from_store_detail', 'to_location', 'transfer_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class TransferRawDetailInline(admin.TabularInline):
    model = models.TransferRawDetailModel
    form = TransferRawDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "调拨明细"
    verbose_name_plural = "调拨明细"

    # 明细表单字段配置
    fields = ('from_store_detail', 'transfer_num', 'to_location')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('from_store_detail',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class TransferRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.TransferRawOrderModel

        fields = ['orderId', 'date']


@admin.register(models.TransferRawOrderModel)
class TransferRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = TransferRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('orderId',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [TransferRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.transferrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.transferrawdetailmodel_set.aggregate(
            total=Sum('transfer_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总调拨数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.TransferRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的调拨单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.TransferRawDetailModel)
class TransferRawDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'transfer_order_link', 'from_store_detail', 'transfer_num',  'to_location',  'to_store_detail')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'transfer_order__orderId',  # 关联入库单号
        'from_store_detail__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'from_store_detail__raw__standard',  # 按执行标准筛选
        'from_store_detail__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('transfer_order', 'from_store_detail')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def transfer_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_transferrawordermodel_change', args=[obj.transfer_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.transfer_order.orderId  # 显示入库单号
        )

    transfer_order_link.short_description = "调拨单号"
    transfer_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.TransferRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的调拨明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions



class LossRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.LossRawDetailModel
        fields = ('raw', 'loss_num')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class LossRawDetailInline(admin.TabularInline):
    model = models.LossRawDetailModel
    form = LossRawDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "报损明细"
    verbose_name_plural = "报损明细"

    # 明细表单字段配置
    fields = ('raw', 'loss_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class LossRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.LossRawOrderModel

        fields = ['orderId', 'date']


# @admin.register(models.LossRawDetailModel)
class LossRawDetailModelAdmin(admin.ModelAdmin):
    """报损明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'loss_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'loss_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('loss_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_lossrawordermodel_change', args=[obj.loss_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.loss_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报损单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.LossRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报损明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
@admin.register(models.LossRawOrderModel)
class LossRawOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = LossRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_loss_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [LossRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date','remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request, object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """


        parms = {
            'orderId': request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'remark': request.POST.get('remark',''),

        }
        _fileds = []
        details_counts = request.POST.get('lossrawdetailmodel_set-TOTAL_FORMS','0')

        for i in range(int(details_counts)):
            raw = models.StoreRawDetailModel.objects.filter(
                pk=request.POST.get(f'lossrawdetailmodel_set-{i}-raw')).first(),

            _fileds.append({
                'id': request.POST.get(f'lossrawdetailmodel_set-{i}-id'),
                'loss_order': request.POST.get(f'lossrawdetailmodel_set-{i}-loss_order'),
                'name': raw[0].raw.name,
                'gui_ge': raw[0].raw.gui_ge,
                'code': raw[0].raw.code,
                'chan_di': raw[0].raw.chan_di,
                'remark': raw[0].raw.remark,
                'standard': str(raw[0].raw.standard.name),
                'storage_condition': raw[0].raw.storage_condition,

                'loss_num': request.POST.get(f'lossrawdetailmodel_set-{i}-loss_num'),
                'unit': raw[0].unit.unit,
                'price': str(raw[0].price),
                'tax': str(raw[0].tax),
                'amount': str(raw[0].price * raw[0].tax),
                'batch_number': raw[0].batch_number,
                'location': raw[0].location.name,

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
            'model': code,
            'parms': parms,
            'report_type': '0',
            'fileds': _fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.lossrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_loss_num(self, obj):
        from django.db.models import Sum
        total = obj.lossrawdetailmodel_set.aggregate(
            total=Sum('loss_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_loss_num.short_description = "总报损数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.LossRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报损单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class SurplusRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.SurplusRawDetailModel
        fields = ('raw', 'surplus_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SurplusRawDetailInline(admin.TabularInline):
    model = models.SurplusRawDetailModel
    form = SurplusRawDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "报溢明细"
    verbose_name_plural = "报溢明细"

    # 明细表单字段配置
    fields = ('raw', 'surplus_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields




# 1. 自定义入库单表单，添加校验逻辑
class SurplusRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.SurplusRawOrderModel

        fields = ['orderId', 'date']


# @admin.register(models.SurplusRawDetailModel)
class SurplusRawDetailModelAdmin(admin.ModelAdmin):
    """报溢明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'surplus_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'surplus_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('surplus_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_surplusrawordermodel_change', args=[obj.surplus_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.surplus_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报溢单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SurplusRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报溢单明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

@admin.register(models.SurplusRawOrderModel)
class SurplusRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SurplusRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_surplus_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SurplusRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.surplusrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_surplus_num(self, obj):
        from django.db.models import Sum
        total = obj.surplusrawdetailmodel_set.aggregate(
            total=Sum('surplus_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_surplus_num.short_description = "总报溢数量"
    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SurplusRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报溢单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class SellRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellRawDetailModel
        fields = ('raw', 'sell_num')

# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellRawDetailInline(admin.TabularInline):
    model = models.SellRawDetailModel
    form = SellRawDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "销售明细"
    verbose_name_plural = "销售明细"

    # 明细表单字段配置
    fields = ('raw', 'sell_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class SellRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellRawOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellRawOrderModel)
class SellRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_sell_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_sell_num(self, obj):
        from django.db.models import Sum
        total = obj.sellrawdetailmodel_set.aggregate(
            total=Sum('sell_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_sell_num.short_description = "总销售数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.SellRawDetailModel)
class SellRawDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sell_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sell_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sell_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellrawordermodel_change', args=[obj.sell_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sell_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False


    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OutboundRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundRawDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundRawDetailInline(admin.TabularInline):
    model = models.OutboundRawDetailModel
    form = OutboundRawDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundRawOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundRawOrderModel)
class OutboundRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundrawdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)

        # 记录变更日志
        log_model_changes(self, request, obj, form, change)

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundRawDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundrawordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OtherOutboundRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundRawDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OtherOutboundRawDetailInline(admin.TabularInline):
    model = models.OtherOutboundRawDetailModel
    form = OtherOutboundRawDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OtherOutboundRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundRawOrderModel

        fields = ['orderId', 'date',]


@admin.register(models.OtherOutboundRawOrderModel)
class OtherOutboundRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OtherOutboundRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OtherOutboundRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.otheroutboundrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.otheroutboundrawdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OtherOutboundRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
@admin.register(models.OtherOutboundRawDetailModel)
class OtherOutboundRawDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_otheroutboundrawordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OtherOutboundRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class BackRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackRawDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackRawDetailInline(admin.TabularInline):
    model = models.BackRawDetailModel
    form = BackRawDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackRawOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackRawOrderModel)
class BackRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backrawdetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.BackRawDetailModel)
class BackRawDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backrawordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OutboundRawOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundRawOfIntermediateProductDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundRawOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.OutboundRawOfIntermediateProductDetailModel
    form = OutboundRawOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundRawOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundRawOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundRawOfIntermediateProductOrderModel)
class OutboundRawOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundRawOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundRawOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundrawofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundrawofintermediateproductdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundRawOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundrawofintermediateproductordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundRawOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class BackRawOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackRawOfIntermediateProductDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackRawOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.BackRawOfIntermediateProductDetailModel
    form = BackRawOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackRawOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackRawOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackRawOfIntermediateProductOrderModel)
class BackRawOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackRawOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackRawOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backrawofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backrawofintermediateproductdetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackRawOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.BackRawOfIntermediateProductDetailModel)
class BackRawOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backrawofintermediateproductordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackRawOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions




class SellBackRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellBackRawDetailModel
        fields = ('raw', 'sellback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellBackRawDetailInline(admin.TabularInline):
    model = models.SellBackRawDetailModel
    form = SellBackRawDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "销售退货明细"
    verbose_name_plural = "销售退货明细"

    # 明细表单字段配置
    fields = ('raw', 'sellback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class SellBackRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellBackRawOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellBackRawOrderModel)
class SellBackRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellBackRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellBackRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellbackrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.sellbackrawdetailmodel_set.aggregate(
            total=Sum('sellback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退货数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellBackRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售退货单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.SellBackRawDetailModel)
class SellBackRawDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sellback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sellback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sellback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellbackrawordermodel_change', args=[obj.sellback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sellback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售退货单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellBackRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售退货明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions




class StoreBackRawDetailForm(forms.ModelForm):
    class Meta:
        model = models.StoreBackRawDetailModel
        fields = ('raw', 'storeback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreBackRawDetailInline(admin.TabularInline):
    model = models.StoreBackRawDetailModel
    form = StoreBackRawDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'storeback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class StoreBackRawOrderForm(forms.ModelForm):
    class Meta:
        model = models.StoreBackRawOrderModel

        fields = ['orderId', 'date', 'supplier']


@admin.register(models.StoreBackRawOrderModel)
class StoreBackRawOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = StoreBackRawOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StoreBackRawDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'supplier'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storebackrawdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.storebackrawdetailmodel_set.aggregate(
            total=Sum('storeback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.StoreBackRawOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.StoreBackRawDetailModel)
class StoreBackRawDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'storeback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'storeback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('storeback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storebackrawordermodel_change', args=[obj.storeback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.storeback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.StoreBackRawDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions




class StoreAdditiveDetailForm(forms.ModelForm):
    # 新增金额字段（不存入数据库，仅用于计算）
    amount = forms.DecimalField(
        label="不含税金额",
        required=False,
        max_digits=12,
        decimal_places=2,
        widget=forms.NumberInput(attrs={
            'class': 'amount-input',  # 用于JS选择
            'step': '0.01'  # 支持小数输入
        })
    )
    class Meta:
        model = models.StoreAdditiveDetailModel
        fields = ('raw', 'store_num','unit')

class StoreAdditiveOrderFileForm(forms.ModelForm):
    class Meta:
        model = models.StoreAdditiveOrderFileModel
        fields = ('id', 'store_order','file')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreAdditiveFileInline(admin.TabularInline):
    model = models.StoreAdditiveOrderFileModel
    form = StoreAdditiveOrderFileForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    classes = ['collapse'] # 添加collapse类，这是Django Admin内置的
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "附件"
    verbose_name_plural = "附件"

    # 明细表单字段配置
    fields = ('file',)


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ()  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题

# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreAdditiveDetailInline(admin.TabularInline):
    model = models.StoreAdditiveDetailModel
    form = StoreAdditiveDetailForm  # 应用自定义表单
    template = 'store/custom_tabular.html'  # 加载自定义模板
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "入库明细"
    verbose_name_plural = "入库明细"

    # 明细表单字段配置
    fields = ('raw', 'store_num', 'unit', 'price','tax','amount', 'batch_number','location')


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw','unit')  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题
    def get_queryset(self, request):
        """
        重写查询集：只返回当前入库单关联的、且parent字段为空的明细数据
        - 父类的get_queryset已自动过滤出当前入库单（store_order=当前主表对象）的数据
        - 额外添加parent__isnull=True，过滤掉parent有数值的记录
        """
        qs = super().get_queryset(request)
        # 核心过滤条件：parent为空（parent__isnull=True）
        return qs.filter(parent__isnull=True)
# 1. 自定义入库单表单，添加校验逻辑
class StoreAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.StoreAdditiveOrderModel

        fields=['orderId', 'date','type','supplier']



@admin.register(models.StoreAdditiveOrderModel)
class StoreAdditiveOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = StoreAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_store_num','type','invoice', 'create_at','view_details_link')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId','supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StoreAdditiveDetailInline,StoreAdditiveFileInline]

    # 表单字段分组
    fieldsets = (
        ('入库单基本信息', {
            'fields': ('orderId', 'date','type','invoice','supplier','remark'),
            'description': '请输入入库单号和入库日期'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request,object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """

        # parms=request.GET
        parms ={
            'orderId':request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'type': request.POST.get('type'),
            'invoice': request.POST.get('invoice'),
            'supplier': request.POST.get('supplier'),
            'supplier_name':baseModels.SupplierAdditiveModel.objects.filter(pk=request.POST.get('supplier',0)).first().name
        }
        _fileds=[]
        details_counts=request.POST.get('storeadditivedetailmodel_set-TOTAL_FORMS')

        for i in range(int(details_counts)):
            raw=baseModels.AdditiveModel.objects.filter(pk=request.POST.get(f'storeadditivedetailmodel_set-{i}-raw')).first(),
            unit = baseModels.UnitModel.objects.filter(pk=request.POST.get(f'storeadditivedetailmodel_set-{i}-unit')).first(),
            _fileds.append({
                'id':request.POST.get(f'storeadditivedetailmodel_set-{i}-id'),
                'store_order': request.POST.get(f'storeadditivedetailmodel_set-{i}-store_order'),
                'name':raw[0].name,
                'gui_ge': raw[0].gui_ge,
                'code': raw[0].code,
                'chan_di': raw[0].chan_di,
                'remark': raw[0].remark,
                'standard': str(raw[0].standard.name),
                'storage_condition': raw[0].storage_condition,

                'store_num': request.POST.get(f'storeadditivedetailmodel_set-{i}-store_num'),
                'unit': unit[0].unit,
                'price': request.POST.get(f'storeadditivedetailmodel_set-{i}-price'),
                'tax': request.POST.get(f'storeadditivedetailmodel_set-{i}-tax'),
                'amount': request.POST.get(f'storeadditivedetailmodel_set-{i}-amount'),
                'batch_number': request.POST.get(f'storeadditivedetailmodel_set-{i}-batch_number'),
                'location': request.POST.get(f'storeadditivedetailmodel_set-{i}-location'),

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
             'model': code,
            'parms':parms,
            'report_type':'0',
            'fileds':_fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storeadditivedetailmodel_set.filter(parent__isnull=True).count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_store_num(self, obj):
        from django.db.models import Sum
        total = obj.storeadditivedetailmodel_set.filter(parent__isnull=True).aggregate(
            total=Sum('store_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_store_num.short_description = "总入库数量"

    # 自定义字段：生成跳转链接（查看明细详情）
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)

        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/admin/store/storeadditivedetailmodel/?store_order_id={}&parent__isnull=True" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )

    view_details_link.short_description = "操作"  # 表头名称




@admin.register(models.StoreAdditiveDetailModel)
class StoreAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""
    # 新增：指定自定义模板路径
    change_list_template = 'admin/store/storeadditivedetailmodel/changelist.html'
    # 列表页展示字段
    list_display = ('id', 'store_order_link', 'raw','batch_number', 'store_num','unit','price','amount','tax','tax_inclusive_amount','tax_amount','invoice','remaining_num', 'store_order_supplier_name', 'raw_standard', 'create_at','view_details_link','location','get_type')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'store_order__orderId',  # 关联入库单号
        'raw__name', 'raw__code'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__standard',  # 按执行标准筛选
        'raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('store_order', 'raw','unit')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()
    # 分页设置
    list_per_page = 10
    # 自定义列表字段：点击入库单号可跳转到主单
    def store_order_link(self, obj):
        #通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storeadditiveordermodel_change', args=[obj.store_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.store_order.orderId  # 显示入库单号
        )

    store_order_link.short_description = "入库单号"
    store_order_link.allow_tags = True  # 允许HTML渲染
    def amount(self, obj):
        result=obj.store_num * obj.price
        return result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
    amount.short_description = "金额"

    def tax_inclusive_amount(self, obj):
        result = obj.store_num * obj.price * (1+obj.tax *  Decimal('0.01'))
        return  result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)

    tax_inclusive_amount.short_description = "含税金额"
    def store_order_supplier_name(self, obj):
        return obj.store_order.supplier.name

    store_order_supplier_name.short_description = "供应商"
    def invoice(self,obj):
        TYPE_CHOICES = {
            '1':'没有发票',
            '0':'有发票'
        }

        return TYPE_CHOICES.get(obj.store_order.invoice,'发票异常')

    invoice.short_description = "发票"
    def tax_amount(self, obj):
        result = obj.store_num * obj.price * obj.tax * Decimal('0.01')
        return result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
    tax_amount.short_description = "税额"
    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

        # 自定义字段：生成跳转链接（查看明细详情）

    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)
        # 使用外键字段名+_id 作为筛选参数
        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/search/store/storeadditivedetailmodel/subledger/?pk={}" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )
    view_details_link.short_description = "明细账"

    # 自定义列表字段：显示原料的入库类型
    def get_type(self, obj):
        if obj.parent:
            return '调拨'
        elif obj.store_order.type == '1':
            return '入库单'
        else:
            return '期初入库单'

    get_type.short_description = "类型"

    # 动态控制列表显示字段（无权限时移除 view_details_link）
    def get_list_display(self, request):
        # 获取默认的列表字段（原 list_display）
        default_list_display = list(self.list_display)  # 原 list_display 是元组，转列表便于修改

        # 检查权限：无权限则移除 "view_details_link" 字段
        if not request.user.has_perm("store.view_subledger_storeadditivedetailmodel"):
            if "view_details_link" in default_list_display:
                default_list_display.remove("view_details_link")

        return default_list_display

    # 重写changelist_view方法以计算总和
    def changelist_view(self, request, extra_context=None):
        response = super().changelist_view(request, extra_context=extra_context)

        # 尝试获取查询集
        try:
            cl = response.context_data['cl']
            queryset = cl.queryset
            # 获取分页后的当前页数据，而不是完整查询集
            page_queryset = cl.result_list  # 这是分页后的当前页数据
            # 计算需要求和的字段
            totals = queryset.aggregate(
                total_store_num=Coalesce(Sum(
                    ExpressionWrapper(F('store_num'), output_field=DecimalField())
                ), Decimal('0.00')),
                total_amount=Coalesce(Sum(
                    ExpressionWrapper(
                        F('store_num') * F('price'),
                        output_field=DecimalField(max_digits=12, decimal_places=2)
                    )
                ), Decimal('0.00')),
                total_tax_amount=Coalesce(Sum(
                    ExpressionWrapper(
                        F('store_num') * F('price') * F('tax') * Decimal('0.01'),
                        output_field=DecimalField(max_digits=12, decimal_places=2)
                    )
                ), Decimal('0.00')),
                total_tax_inclusive=Coalesce(Sum(
                    ExpressionWrapper(
                        F('store_num') * F('price') * (Decimal('1') + F('tax') * Decimal('0.01')),
                        output_field=DecimalField(max_digits=12, decimal_places=2)
                    )
                ), Decimal('0.00')),
            )
            # 计算需要求和的字段
            page_totals = page_queryset.aggregate(
                total_store_num=Coalesce(Sum(
                    ExpressionWrapper(F('store_num'), output_field=DecimalField())
                ), Decimal('0.00')),
                total_amount=Coalesce(Sum(
                    ExpressionWrapper(
                        F('store_num') * F('price'),
                        output_field=DecimalField(max_digits=12, decimal_places=2)
                    )
                ), Decimal('0.00')),
                total_tax_amount=Coalesce(Sum(
                    ExpressionWrapper(
                        F('store_num') * F('price') * F('tax') * Decimal('0.01'),
                        output_field=DecimalField(max_digits=12, decimal_places=2)
                    )
                ), Decimal('0.00')),
                total_tax_inclusive=Coalesce(Sum(
                    ExpressionWrapper(
                        F('store_num') * F('price') * (Decimal('1') + F('tax') * Decimal('0.01')),
                        output_field=DecimalField(max_digits=12, decimal_places=2)
                    )
                ), Decimal('0.00')),
            )

            # 添加到上下文
            response.context_data['totals'] = totals
            response.context_data['page_totals'] = page_totals
        except (AttributeError, KeyError):
            # 如果获取查询集失败，不添加总计
            pass

        return response
class TransferAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.TransferAdditiveDetailModel
        fields = ('from_store_detail', 'to_location', 'transfer_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class TransferAdditiveDetailInline(admin.TabularInline):
    model = models.TransferAdditiveDetailModel
    form = TransferAdditiveDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "调拨明细"
    verbose_name_plural = "调拨明细"

    # 明细表单字段配置
    fields = ('from_store_detail', 'transfer_num', 'to_location')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('from_store_detail',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class TransferAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.TransferAdditiveOrderModel

        fields = ['orderId', 'date']


@admin.register(models.TransferAdditiveOrderModel)
class TransferAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = TransferAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('orderId',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [TransferAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.transferadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.transferadditivedetailmodel_set.aggregate(
            total=Sum('transfer_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总调拨数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.TransferAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的调拨单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.TransferAdditiveDetailModel)
class TransferAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'transfer_order_link', 'from_store_detail', 'transfer_num',  'to_location',  'to_store_detail')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'transfer_order__orderId',  # 关联入库单号
        'from_store_detail__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'from_store_detail__raw__standard',  # 按执行标准筛选
        'from_store_detail__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('transfer_order', 'from_store_detail')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def transfer_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_transferadditiveordermodel_change', args=[obj.transfer_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.transfer_order.orderId  # 显示入库单号
        )

    transfer_order_link.short_description = "调拨单号"
    transfer_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.TransferAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的调拨明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class LossAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.LossAdditiveDetailModel
        fields = ('raw', 'loss_num')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class LossAdditiveDetailInline(admin.TabularInline):
    model = models.LossAdditiveDetailModel
    form = LossAdditiveDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "报损明细"
    verbose_name_plural = "报损明细"

    # 明细表单字段配置
    fields = ('raw', 'loss_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class LossAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.LossAdditiveOrderModel

        fields = ['orderId', 'date']


@admin.register(models.LossAdditiveDetailModel)
class LossAdditiveDetailModelAdmin(admin.ModelAdmin):
    """报损明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'loss_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'loss_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('loss_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_lossadditiveordermodel_change', args=[obj.loss_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.loss_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报损单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.LossAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报损明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
@admin.register(models.LossAdditiveOrderModel)
class LossAdditiveOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = LossAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_loss_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [LossAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date','remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request, object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """


        parms = {
            'orderId': request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'remark': request.POST.get('remark',''),

        }
        _fileds = []
        details_counts = request.POST.get('lossadditivedetailmodel_set-TOTAL_FORMS','0')

        for i in range(int(details_counts)):
            raw = models.StoreAdditiveDetailModel.objects.filter(
                pk=request.POST.get(f'lossadditivedetailmodel_set-{i}-raw')).first(),

            _fileds.append({
                'id': request.POST.get(f'lossadditivedetailmodel_set-{i}-id'),
                'loss_order': request.POST.get(f'lossadditivedetailmodel_set-{i}-loss_order'),
                'name': raw[0].raw.name,
                'gui_ge': raw[0].raw.gui_ge,
                'code': raw[0].raw.code,
                'chan_di': raw[0].raw.chan_di,
                'remark': raw[0].raw.remark,
                'standard': str(raw[0].raw.standard.name),
                'storage_condition': raw[0].raw.storage_condition,

                'loss_num': request.POST.get(f'lossadditivedetailmodel_set-{i}-loss_num'),
                'unit': raw[0].unit.unit,
                'price': str(raw[0].price),
                'tax': str(raw[0].tax),
                'amount': str(raw[0].price * raw[0].tax),
                'batch_number': raw[0].batch_number,
                'location': raw[0].location.name,

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
            'model': code,
            'parms': parms,
            'report_type': '0',
            'fileds': _fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.lossadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_loss_num(self, obj):
        from django.db.models import Sum
        total = obj.lossadditivedetailmodel_set.aggregate(
            total=Sum('loss_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_loss_num.short_description = "总报损数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.LossAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报损单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class SurplusAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.SurplusAdditiveDetailModel
        fields = ('raw', 'surplus_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SurplusAdditiveDetailInline(admin.TabularInline):
    model = models.SurplusAdditiveDetailModel
    form = SurplusAdditiveDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "报溢明细"
    verbose_name_plural = "报溢明细"

    # 明细表单字段配置
    fields = ('raw', 'surplus_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields




# 1. 自定义入库单表单，添加校验逻辑
class SurplusAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.SurplusAdditiveOrderModel

        fields = ['orderId', 'date']


@admin.register(models.SurplusAdditiveDetailModel)
class SurplusAdditiveDetailModelAdmin(admin.ModelAdmin):
    """报溢明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'surplus_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'surplus_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('surplus_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_surplusadditiveordermodel_change', args=[obj.surplus_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.surplus_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报溢单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SurplusAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报溢单明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

@admin.register(models.SurplusAdditiveOrderModel)
class SurplusAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SurplusAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_surplus_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SurplusAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.surplusadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_surplus_num(self, obj):
        from django.db.models import Sum
        total = obj.surplusadditivedetailmodel_set.aggregate(
            total=Sum('surplus_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_surplus_num.short_description = "总报溢数量"
    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SurplusAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报溢单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class SellAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellAdditiveDetailModel
        fields = ('raw', 'sell_num')

# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellAdditiveDetailInline(admin.TabularInline):
    model = models.SellAdditiveDetailModel
    form = SellAdditiveDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "销售明细"
    verbose_name_plural = "销售明细"

    # 明细表单字段配置
    fields = ('raw', 'sell_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class SellAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellAdditiveOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellAdditiveOrderModel)
class SellAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_sell_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.selladditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_sell_num(self, obj):
        from django.db.models import Sum
        total = obj.selladditivedetailmodel_set.aggregate(
            total=Sum('sell_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_sell_num.short_description = "总销售数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.SellRawDetailModel)
class SellAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sell_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sell_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sell_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_selladditiveordermodel_change', args=[obj.sell_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sell_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False


    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OutboundAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundAdditiveDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundAdditiveDetailInline(admin.TabularInline):
    model = models.OutboundAdditiveDetailModel
    form = OutboundAdditiveDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundAdditiveOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundAdditiveOrderModel)
class OutboundAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundadditivedetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundadditiveordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OtherOutboundAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundAdditiveDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OtherOutboundAdditiveDetailInline(admin.TabularInline):
    model = models.OtherOutboundAdditiveDetailModel
    form = OtherOutboundAdditiveDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OtherOutboundAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundAdditiveOrderModel

        fields = ['orderId', 'date',]


@admin.register(models.OtherOutboundAdditiveOrderModel)
class OtherOutboundAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OtherOutboundAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OtherOutboundAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.otheroutboundadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.otheroutboundadditivedetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OtherOutboundAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
@admin.register(models.OtherOutboundAdditiveDetailModel)
class OtherOutboundAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_otheroutboundadditiveordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OtherOutboundAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class BackAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackAdditiveDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackAdditiveDetailInline(admin.TabularInline):
    model = models.BackAdditiveDetailModel
    form = BackAdditiveDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackAdditiveOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackAdditiveOrderModel)
class BackAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backadditivedetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.BackAdditiveDetailModel)
class BackAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backadditiveordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class OutboundAdditiveOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundAdditiveOfIntermediateProductDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundAdditiveOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.OutboundAdditiveOfIntermediateProductDetailModel
    form = OutboundAdditiveOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundAdditiveOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundAdditiveOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundAdditiveOfIntermediateProductOrderModel)
class OutboundAdditiveOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundAdditiveOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundAdditiveOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundadditiveofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundadditiveofintermediateproductdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundAdditiveOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundAdditiveOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundadditiveofintermediateproductordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundAdditiveOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class BackAdditiveOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackAdditiveOfIntermediateProductDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackAdditiveOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.BackAdditiveOfIntermediateProductDetailModel
    form = BackAdditiveOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackAdditiveOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackAdditiveOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackAdditiveOfIntermediateProductOrderModel)
class BackAdditiveOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackAdditiveOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackAdditiveOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backadditiveofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backadditiveofintermediateproductdetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackAdditiveOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.BackAdditiveOfIntermediateProductDetailModel)
class BackAdditiveOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backadditiveofintermediateproductordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackAdditiveOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions



class SellBackAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellBackAdditiveDetailModel
        fields = ('raw', 'sellback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellBackAdditiveDetailInline(admin.TabularInline):
    model = models.SellBackAdditiveDetailModel
    form = SellBackAdditiveDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "销售退货明细"
    verbose_name_plural = "销售退货明细"

    # 明细表单字段配置
    fields = ('raw', 'sellback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class SellBackAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellBackAdditiveOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellBackAdditiveOrderModel)
class SellBackAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellBackAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellBackAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellbackadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.sellbackadditivedetailmodel_set.aggregate(
            total=Sum('sellback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退货数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellBackAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售退货单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.SellBackRawDetailModel)
class SellBackAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sellback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sellback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sellback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellbackadditiveordermodel_change', args=[obj.sellback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sellback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售退货单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellBackAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售退货明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions




class StoreBackAdditiveDetailForm(forms.ModelForm):
    class Meta:
        model = models.StoreBackAdditiveDetailModel
        fields = ('raw', 'storeback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreBackAdditiveDetailInline(admin.TabularInline):
    model = models.StoreBackAdditiveDetailModel
    form = StoreBackAdditiveDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'storeback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class StoreBackAdditiveOrderForm(forms.ModelForm):
    class Meta:
        model = models.StoreBackAdditiveOrderModel

        fields = ['orderId', 'date', 'supplier']


@admin.register(models.StoreBackAdditiveOrderModel)
class StoreBackAdditiveOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = StoreBackAdditiveOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StoreBackAdditiveDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'supplier'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storebackadditivedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.storebackadditivedetailmodel_set.aggregate(
            total=Sum('storeback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.StoreBackAdditiveOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.StoreBackRawDetailModel)
class StoreBackAdditiveDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'storeback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'storeback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('storeback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storebackadditiveordermodel_change', args=[obj.storeback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.storeback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.StoreBackAdditiveDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions



class StorePackagingDetailForm(forms.ModelForm):
    # 新增金额字段（不存入数据库，仅用于计算）
    amount = forms.DecimalField(
        label="不含税金额",
        required=False,
        max_digits=12,
        decimal_places=2,
        widget=forms.NumberInput(attrs={
            'class': 'amount-input',  # 用于JS选择
            'step': '0.01'  # 支持小数输入
        })
    )
    class Meta:
        model = models.StorePackagingDetailModel
        fields = ('raw', 'store_num','unit')

class StorePackagingOrderFileForm(forms.ModelForm):
    class Meta:
        model = models.StorePackagingOrderFileModel
        fields = ('id', 'store_order','file')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class StorePackagingFileInline(admin.TabularInline):
    model = models.StorePackagingOrderFileModel
    form = StorePackagingOrderFileForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    classes = ['collapse'] # 添加collapse类，这是Django Admin内置的
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "附件"
    verbose_name_plural = "附件"

    # 明细表单字段配置
    fields = ('file',)


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ()  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题

# 明细项内嵌编辑（在入库单页面直接管理明细）
class StorePackagingDetailInline(admin.TabularInline):
    model = models.StorePackagingDetailModel
    form = StorePackagingDetailForm  # 应用自定义表单
    template = 'store/custom_tabular.html'  # 加载自定义模板
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "入库明细"
    verbose_name_plural = "入库明细"

    # 明细表单字段配置
    fields = ('raw', 'store_num', 'unit', 'price','tax','amount', 'batch_number','location')


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw','unit')  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题
    def get_queryset(self, request):
        """
        重写查询集：只返回当前入库单关联的、且parent字段为空的明细数据
        - 父类的get_queryset已自动过滤出当前入库单（store_order=当前主表对象）的数据
        - 额外添加parent__isnull=True，过滤掉parent有数值的记录
        """
        qs = super().get_queryset(request)
        # 核心过滤条件：parent为空（parent__isnull=True）
        return qs.filter(parent__isnull=True)
# 1. 自定义入库单表单，添加校验逻辑
class StorePackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.StorePackagingOrderModel

        fields=['orderId', 'date','type','supplier']



@admin.register(models.StorePackagingOrderModel)
class StorePackagingOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = StorePackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_store_num','type','invoice', 'create_at','view_details_link')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId','supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StorePackagingDetailInline,StorePackagingFileInline]

    # 表单字段分组
    fieldsets = (
        ('入库单基本信息', {
            'fields': ('orderId', 'date','type','invoice','supplier','remark'),
            'description': '请输入入库单号和入库日期'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    def print_one_action(self, request, object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """

        # parms=request.GET
        parms = {
            'orderId': request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'type': request.POST.get('type'),
            'invoice': request.POST.get('invoice'),
            'supplier': request.POST.get('supplier'),
            'supplier_name': baseModels.SupplierPackagingModel.objects.filter(
                pk=request.POST.get('supplier', 0)).first().name
        }
        _fileds = []
        details_counts = request.POST.get('storepackagingdetailmodel_set-TOTAL_FORMS')

        for i in range(int(details_counts)):
            raw = baseModels.PackagingModel.objects.filter(
                pk=request.POST.get(f'storepackagingdetailmodel_set-{i}-raw')).first(),
            unit = baseModels.UnitModel.objects.filter(
                pk=request.POST.get(f'storepackagingdetailmodel_set-{i}-unit')).first(),
            _fileds.append({
                'id': request.POST.get(f'storepackagingdetailmodel_set-{i}-id'),
                'store_order': request.POST.get(f'storepackagingdetailmodel_set-{i}-store_order'),
                'name': raw[0].name,
                'gui_ge': raw[0].gui_ge,
                'code': raw[0].code,
                'chan_di': raw[0].chan_di,
                'remark': raw[0].remark,
                'standard': str(raw[0].standard.name),
                'storage_condition': raw[0].storage_condition,

                'store_num': request.POST.get(f'storepackagingdetailmodel_set-{i}-store_num'),
                'unit': unit[0].unit,
                'price': request.POST.get(f'storepackagingdetailmodel_set-{i}-price'),
                'tax': request.POST.get(f'storepackagingdetailmodel_set-{i}-tax'),
                'amount': request.POST.get(f'storepackagingdetailmodel_set-{i}-amount'),
                'batch_number': request.POST.get(f'storepackagingdetailmodel_set-{i}-batch_number'),
                'location': request.POST.get(f'storepackagingdetailmodel_set-{i}-location'),

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
            'model': code,
            'parms': parms,
            'report_type': '0',
            'fileds': _fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storepackagingdetailmodel_set.filter(parent__isnull=True).count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_store_num(self, obj):
        from django.db.models import Sum
        total = obj.storepackagingdetailmodel_set.filter(parent__isnull=True).aggregate(
            total=Sum('store_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_store_num.short_description = "总入库数量"

    # 自定义字段：生成跳转链接（查看明细详情）
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)

        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/admin/store/storepackagingdetailmodel/?store_order_id={}&parent__isnull=True" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )

    view_details_link.short_description = "操作"  # 表头名称

    def delete_model(self, request, obj):
        """
        拦截详情页的删除操作：
        1. 调用模型的 delete 方法（触发验证）
        2. 捕获 ValidationError 并显示弹窗
        """
        try:
            obj.delete()  # 触发模型的 delete 方法（验证是否关联发票）
            messages.success(request, f"入库单 {obj.orderId} 已成功删除。")
        except ValidationError as e:
            print(str(e))
            # 显示错误信息（弹窗）
            # messages.error(request, str(e))
            # 添加错误消息（明确指定 request 和 level）
            self.message_user(request, str(e), level=messages.ERROR)
    def response_delete(self, request, obj_display, obj_id):
        """删除后的响应处理：重定向回详情页（若删除失败）或列表页（若成功）"""
        # 获取消息列表（重要：必须先获取，否则消息会被标记为已处理）
        messages_list = list(messages.get_messages(request))

        # 检查是否有错误消息
        has_error = any(msg.level == messages.ERROR for msg in messages_list)

        if has_error:
            # 重新添加消息到请求（因为 get_messages 会清空消息）
            for msg in messages_list:
                messages.add_message(request, msg.level, msg.message)
            # # 重定向回详情页
            # return HttpResponseRedirect(reverse('admin:store_storepackagingordermodel_change', args=[obj_id]))
            # 无论成功或失败，都重定向回列表页
            return HttpResponseRedirect(reverse('admin:store_storepackagingordermodel_changelist'))
        else:
            # 无错误，正常跳转
            return super().response_delete(request, obj_display, obj_id)

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.StorePackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的入库单已成功删除。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的入库单"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.StorePackagingDetailModel)
class StorePackagingDetailModelAdmin(DefineImportExportModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'store_order_link', 'raw','batch_number', 'store_num','price','unit','amount','tax','tax_inclusive_amount','tax_amount','invoice','remaining_num', 'store_order_supplier_name','raw_standard', 'create_at','view_details_link','location','get_type')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'store_order__orderId',  # 关联入库单号
        'raw__name', 'raw__code'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__standard',  # 按执行标准筛选
        'raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('store_order', 'raw','unit')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def store_order_link(self, obj):
        #通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storepackagingordermodel_change', args=[obj.store_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.store_order.orderId  # 显示入库单号
        )

    store_order_link.short_description = "入库单号"
    store_order_link.allow_tags = True  # 允许HTML渲染
    def amount(self, obj):
        result=obj.store_num * obj.price
        return result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
    amount.short_description = "不含税金额"

    def tax_inclusive_amount(self, obj):
        result = obj.store_num * obj.price * (1+obj.tax *  Decimal('0.01'))
        return  result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)

    tax_inclusive_amount.short_description = "含税金额"
    def store_order_supplier_name(self, obj):
        return obj.store_order.supplier.name

    store_order_supplier_name.short_description = "供应商"
    def invoice(self,obj):
        TYPE_CHOICES = {
            '1':'没有发票',
            '0':'有发票'
        }

        return TYPE_CHOICES.get(obj.store_order.invoice,'发票异常')

    invoice.short_description = "发票"
    def tax_amount(self, obj):
        result = obj.store_num * obj.price * obj.tax * Decimal('0.01')
        return result.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
    tax_amount.short_description = "税额"
    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)
        # 使用外键字段名+_id 作为筛选参数
        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/search/store/storepackagingdetailmodel/subledger/?pk={}" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )
    view_details_link.short_description = "明细账"

    # 自定义列表字段：显示原料的入库类型
    def get_type(self, obj):
        if obj.parent:
            return '调拨'
        elif obj.store_order.type == '1':
            return '入库单'
        else:
            return '期初入库单'

    get_type.short_description = "类型"
    # 动态控制列表显示字段（无权限时移除 view_details_link）
    def get_list_display(self, request):
        # 获取默认的列表字段（原 list_display）
        default_list_display = list(self.list_display)  # 原 list_display 是元组，转列表便于修改

        # 检查权限：无权限则移除 "view_details_link" 字段
        if not request.user.has_perm("store.view_subledger_storepackagingdetailmodel"):
            if "view_details_link" in default_list_display:
                default_list_display.remove("view_details_link")

        return default_list_display

class TransferPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.TransferPackagingDetailModel
        fields = ('from_store_detail', 'to_location', 'transfer_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class TransferPackagingDetailInline(admin.TabularInline):
    model = models.TransferPackagingDetailModel
    form = TransferPackagingDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "调拨明细"
    verbose_name_plural = "调拨明细"

    # 明细表单字段配置
    fields = ('from_store_detail', 'transfer_num', 'to_location')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('from_store_detail',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class TransferPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.TransferPackagingOrderModel

        fields = ['orderId', 'date']


@admin.register(models.TransferPackagingOrderModel)
class TransferPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = TransferPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('orderId',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [TransferPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.transferpackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.transferpackagingdetailmodel_set.aggregate(
            total=Sum('transfer_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总调拨数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.TransferPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的调拨单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.TransferPackagingDetailModel)
class TransferPackagingDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'transfer_order_link', 'from_store_detail', 'transfer_num',  'to_location',  'to_store_detail')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'transfer_order__orderId',  # 关联入库单号
        'from_store_detail__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'from_store_detail__raw__standard',  # 按执行标准筛选
        'from_store_detail__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('transfer_order', 'from_store_detail')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def transfer_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_transferpackagingordermodel_change', args=[obj.transfer_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.transfer_order.orderId  # 显示入库单号
        )

    transfer_order_link.short_description = "调拨单号"
    transfer_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.TransferPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的调拨明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class LossPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.LossPackagingDetailModel
        fields = ('raw', 'loss_num')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class LossPackagingDetailInline(admin.TabularInline):
    model = models.LossPackagingDetailModel
    form = LossPackagingDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "报损明细"
    verbose_name_plural = "报损明细"

    # 明细表单字段配置
    fields = ('raw', 'loss_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class LossPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.LossPackagingOrderModel

        fields = ['orderId', 'date','remark']


# @admin.register(models.LossRawDetailModel)
class LossPackagingDetailModelAdmin(admin.ModelAdmin):
    """报损明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'loss_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'loss_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('loss_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_losspackagingordermodel_change', args=[obj.loss_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.loss_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报损单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.LossPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报损明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
@admin.register(models.LossPackagingOrderModel)
class LossPackagingOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = LossPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_loss_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [LossPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date','remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request, object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """


        parms = {
            'orderId': request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'remark': request.POST.get('remark'),
            # 'supplier_name': baseModels.SupplierAdditiveModel.objects.filter(
            #     pk=request.POST.get('supplier', 0)).first().name
        }
        _fileds = []
        details_counts = request.POST.get('losspackagingdetailmodel_set-TOTAL_FORMS','0')

        for i in range(int(details_counts)):
            raw = models.StorePackagingDetailModel.objects.filter(
                pk=request.POST.get(f'losspackagingdetailmodel_set-{i}-raw')).first(),

            _fileds.append({
                'id': request.POST.get(f'losspackagingdetailmodel_set-{i}-id'),
                'loss_order': request.POST.get(f'losspackagingdetailmodel_set-{i}-loss_order'),
                'name': raw[0].raw.name,
                'gui_ge': raw[0].raw.gui_ge,
                'code': raw[0].raw.code,
                'chan_di': raw[0].raw.chan_di,
                'remark': raw[0].raw.remark,
                'standard': str(raw[0].raw.standard.name),
                'storage_condition': raw[0].raw.storage_condition,

                'loss_num': request.POST.get(f'losspackagingdetailmodel_set-{i}-loss_num'),
                'unit': raw[0].unit.unit,
                'price': str(raw[0].price),
                'tax': str(raw[0].tax),
                'amount': str(raw[0].price * raw[0].tax),
                'batch_number': raw[0].batch_number,
                'location': raw[0].location.name,

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
            'model': code,
            'parms': parms,
            'report_type': '0',
            'fileds': _fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.losspackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_loss_num(self, obj):
        from django.db.models import Sum
        total = obj.losspackagingdetailmodel_set.aggregate(
            total=Sum('loss_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_loss_num.short_description = "总报损数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.LossPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报损单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class SurplusPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.SurplusPackagingDetailModel
        fields = ('raw', 'surplus_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SurplusPackagingDetailInline(admin.TabularInline):
    model = models.SurplusPackagingDetailModel
    form = SurplusPackagingDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "报溢明细"
    verbose_name_plural = "报溢明细"

    # 明细表单字段配置
    fields = ('raw', 'surplus_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields




# 1. 自定义入库单表单，添加校验逻辑
class SurplusPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.SurplusPackagingOrderModel

        fields = ['orderId', 'date']


# @admin.register(models.SurplusRawDetailModel)
class SurplusPackagingDetailModelAdmin(admin.ModelAdmin):
    """报溢明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'surplus_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'surplus_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('surplus_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_surpluspackagingordermodel_change', args=[obj.surplus_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.surplus_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报溢单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SurplusPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报溢单明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

@admin.register(models.SurplusPackagingOrderModel)
class SurplusPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SurplusPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_surplus_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SurplusPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.surpluspackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_surplus_num(self, obj):
        from django.db.models import Sum
        total = obj.surpluspackagingdetailmodel_set.aggregate(
            total=Sum('surplus_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_surplus_num.short_description = "总报溢数量"
    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SurplusPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报溢单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class SellPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellPackagingDetailModel
        fields = ('raw', 'sell_num')

# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellPackagingDetailInline(admin.TabularInline):
    model = models.SellPackagingDetailModel
    form = SellPackagingDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "销售明细"
    verbose_name_plural = "销售明细"

    # 明细表单字段配置
    fields = ('raw', 'sell_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class SellPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellPackagingOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellPackagingOrderModel)
class SellPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_sell_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellpackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_sell_num(self, obj):
        from django.db.models import Sum
        total = obj.sellpackagingdetailmodel_set.aggregate(
            total=Sum('sell_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_sell_num.short_description = "总销售数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.SellRawDetailModel)
class SellPackagingDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sell_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sell_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sell_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellpackagingordermodel_change', args=[obj.sell_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sell_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False


    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OutboundPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundPackagingDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundPackagingDetailInline(admin.TabularInline):
    model = models.OutboundPackagingDetailModel
    form = OutboundPackagingDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundPackagingOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundPackagingOrderModel)
class OutboundPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundpackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundpackagingdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundPackagingDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundpackagingordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OtherOutboundPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundPackagingDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OtherOutboundPackagingDetailInline(admin.TabularInline):
    model = models.OtherOutboundPackagingDetailModel
    form = OtherOutboundPackagingDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OtherOutboundPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundPackagingOrderModel

        fields = ['orderId', 'date',]


@admin.register(models.OtherOutboundPackagingOrderModel)
class OtherOutboundPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OtherOutboundPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OtherOutboundPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.otheroutboundpackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.otheroutboundpackagingdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OtherOutboundPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
@admin.register(models.OtherOutboundPackagingDetailModel)
class OtherOutboundPackagingDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_otheroutboundpackagingordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OtherOutboundPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class BackPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackPackagingDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackPackagingDetailInline(admin.TabularInline):
    model = models.BackPackagingDetailModel
    form = BackPackagingDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackPackagingOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackPackagingOrderModel)
class BackPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backpackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backpackagingdetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.BackPackagingDetailModel)
class BackPackagingDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backpackagingordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class OutboundPackagingOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundPackagingOfIntermediateProductDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundPackagingOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.OutboundPackagingOfIntermediateProductDetailModel
    form = OutboundPackagingOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundPackagingOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundPackagingOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundPackagingOfIntermediateProductOrderModel)
class OutboundPackagingOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundPackagingOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundPackagingOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundpackagingofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundpackagingofintermediateproductdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundPackagingOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundPackagingOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundpackagingofintermediateproductordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundPackagingOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class BackPackagingOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackPackagingOfIntermediateProductDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackPackagingOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.BackPackagingOfIntermediateProductDetailModel
    form = BackPackagingOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackPackagingOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackPackagingOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackPackagingOfIntermediateProductOrderModel)
class BackPackagingOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackPackagingOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackPackagingOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backpackagingofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backpackagingofintermediateproductdetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackPackagingOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.BackRawDetailModel)
class BackPackagingOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backpackagingofintermediateproductordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackPackagingOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions



class SellBackPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellBackPackagingDetailModel
        fields = ('raw', 'sellback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellBackPackagingDetailInline(admin.TabularInline):
    model = models.SellBackPackagingDetailModel
    form = SellBackPackagingDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "销售退货明细"
    verbose_name_plural = "销售退货明细"

    # 明细表单字段配置
    fields = ('raw', 'sellback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class SellBackPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellBackPackagingOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellBackPackagingOrderModel)
class SellBackPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellBackPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellBackPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellbackpackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.sellbackpackagingdetailmodel_set.aggregate(
            total=Sum('sellback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退货数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellBackPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售退货单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.SellBackRawDetailModel)
class SellBackPackagingDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sellback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sellback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sellback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellbackpackagingordermodel_change', args=[obj.sellback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sellback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售退货单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellBackPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售退货明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions




class StoreBackPackagingDetailForm(forms.ModelForm):
    class Meta:
        model = models.StoreBackPackagingDetailModel
        fields = ('raw', 'storeback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreBackPackagingDetailInline(admin.TabularInline):
    model = models.StoreBackPackagingDetailModel
    form = StoreBackPackagingDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'storeback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class StoreBackPackagingOrderForm(forms.ModelForm):
    class Meta:
        model = models.StoreBackPackagingOrderModel

        fields = ['orderId', 'date', 'supplier']


@admin.register(models.StoreBackPackagingOrderModel)
class StoreBackPackagingOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = StoreBackPackagingOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StoreBackPackagingDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'supplier'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storebackpackagingdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.storebackpackagingdetailmodel_set.aggregate(
            total=Sum('storeback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.StoreBackPackagingOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.StoreBackRawDetailModel)
class StoreBackPackagingDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'storeback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'storeback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('storeback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storebackpackagingordermodel_change', args=[obj.storeback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.storeback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.StoreBackPackagingDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions



class StoreIntermediateDetailForm(forms.ModelForm):
    # 新增金额字段（不存入数据库，仅用于计算）
    amount = forms.DecimalField(
        label="不含税金额",
        required=False,
        max_digits=12,
        decimal_places=2,
        widget=forms.NumberInput(attrs={
            'class': 'amount-input',  # 用于JS选择
            'step': '0.01'  # 支持小数输入
        })
    )
    class Meta:
        model = models.StoreIntermediateDetailModel
        fields = ('raw', 'store_num','unit')

class StoreIntermediateOrderFileForm(forms.ModelForm):
    class Meta:
        model = models.StoreIntermediateOrderFileModel
        fields = ('id', 'store_order','file')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreIntermediateFileInline(admin.TabularInline):
    model = models.StoreIntermediateOrderFileModel
    form = StoreIntermediateOrderFileForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    classes = ['collapse'] # 添加collapse类，这是Django Admin内置的
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "附件"
    verbose_name_plural = "附件"

    # 明细表单字段配置
    fields = ('file',)


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ()  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题

# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreIntermediateDetailInline(admin.TabularInline):
    model = models.StoreIntermediateDetailModel
    form = StoreIntermediateDetailForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    template = 'store/custom_tabular.html'  # 加载自定义模板
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "入库明细"
    verbose_name_plural = "入库明细"

    # 明细表单字段配置
    fields = ('raw', 'store_num', 'unit', 'price','tax','amount', 'batch_number','location')


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw','unit')  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题
    def get_queryset(self, request):
        """
        重写查询集：只返回当前入库单关联的、且parent字段为空的明细数据
        - 父类的get_queryset已自动过滤出当前入库单（store_order=当前主表对象）的数据
        - 额外添加parent__isnull=True，过滤掉parent有数值的记录
        """
        qs = super().get_queryset(request)
        # 核心过滤条件：parent为空（parent__isnull=True）
        return qs.filter(parent__isnull=True)
# 1. 自定义入库单表单，添加校验逻辑
class StoreIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.StoreIntermediateOrderModel

        fields=['orderId', 'date','type','supplier']



@admin.register(models.StoreIntermediateOrderModel)
class StoreIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = StoreIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_store_num','type', 'create_at','view_details_link')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId','supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StoreIntermediateDetailInline,StoreIntermediateFileInline]

    # 表单字段分组
    fieldsets = (
        ('入库单基本信息', {
            'fields': ('orderId', 'date','type','supplier'),
            'description': '请输入入库单号和入库日期'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storeintermediatedetailmodel_set.filter(parent__isnull=True).count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_store_num(self, obj):
        from django.db.models import Sum
        total = obj.storeintermediatedetailmodel_set.filter(parent__isnull=True).aggregate(
            total=Sum('store_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_store_num.short_description = "总入库数量"

    # 自定义字段：生成跳转链接（查看明细详情）
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)

        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/admin/store/storeintermediatedetailmodel/?store_order_id={}&parent__isnull=True" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )

    view_details_link.short_description = "操作"  # 表头名称




@admin.register(models.StoreIntermediateDetailModel)
class StoreIntermediateDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'store_order_link', 'raw','batch_number', 'store_num','unit','remaining_num', 'raw_standard', 'create_at','view_details_link','location','get_type')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'store_order__orderId',  # 关联入库单号
        'raw__name', 'raw__code'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__standard',  # 按执行标准筛选
        'raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('store_order', 'raw','unit')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def store_order_link(self, obj):
        #通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storeintermediateordermodel_change', args=[obj.store_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.store_order.orderId  # 显示入库单号
        )

    store_order_link.short_description = "入库单号"
    store_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)
        # 使用外键字段名+_id 作为筛选参数
        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/search/store/storeintermediatedetailmodel/subledger/?pk={}" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )
    view_details_link.short_description = "明细账"

    # 自定义列表字段：显示原料的入库类型
    def get_type(self, obj):
        if obj.parent:
            return '调拨'
        elif obj.store_order.type == '1':
            return '入库单'
        else:
            return '期初入库单'

    get_type.short_description = "类型"
    # 动态控制列表显示字段（无权限时移除 view_details_link）
    def get_list_display(self, request):
        # 获取默认的列表字段（原 list_display）
        default_list_display = list(self.list_display)  # 原 list_display 是元组，转列表便于修改

        # 检查权限：无权限则移除 "view_details_link" 字段
        if not request.user.has_perm("store.view_subledger_storeintermediatedetailmodel"):
            if "view_details_link" in default_list_display:
                default_list_display.remove("view_details_link")

        return default_list_display


class TransferIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.TransferIntermediateDetailModel
        fields = ('from_store_detail', 'to_location', 'transfer_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class TransferIntermediateDetailInline(admin.TabularInline):
    model = models.TransferIntermediateDetailModel
    form = TransferIntermediateDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "调拨明细"
    verbose_name_plural = "调拨明细"

    # 明细表单字段配置
    fields = ('from_store_detail', 'transfer_num', 'to_location')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('from_store_detail',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class TransferIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.TransferIntermediateOrderModel

        fields = ['orderId', 'date']


@admin.register(models.TransferIntermediateOrderModel)
class TransferIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = TransferIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('orderId',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [TransferIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.transferintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.transferintermediatedetailmodel_set.aggregate(
            total=Sum('transfer_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总调拨数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.TransferIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的调拨单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.TransferIntermediateDetailModel)
class TransferIntermediateDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'transfer_order_link', 'from_store_detail', 'transfer_num',  'to_location',  'to_store_detail')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'transfer_order__orderId',  # 关联入库单号
        'from_store_detail__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'from_store_detail__raw__standard',  # 按执行标准筛选
        'from_store_detail__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('transfer_order', 'from_store_detail')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def transfer_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_transferintermediateordermodel_change', args=[obj.transfer_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.transfer_order.orderId  # 显示入库单号
        )

    transfer_order_link.short_description = "调拨单号"
    transfer_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.TransferIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的调拨明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions



class LossIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.LossIntermediateDetailModel
        fields = ('raw', 'loss_num')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class LossIntermediateDetailInline(admin.TabularInline):
    model = models.LossIntermediateDetailModel
    form = LossIntermediateDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "报损明细"
    verbose_name_plural = "报损明细"

    # 明细表单字段配置
    fields = ('raw', 'loss_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class LossIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.LossIntermediateOrderModel

        fields = ['orderId', 'date']


# @admin.register(models.LossRawDetailModel)
class LossIntermediateDetailModelAdmin(admin.ModelAdmin):
    """报损明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'loss_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'loss_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('loss_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_lossintermediateordermodel_change', args=[obj.loss_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.loss_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报损单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.LossIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报损明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
@admin.register(models.LossIntermediateOrderModel)
class LossIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = LossIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_loss_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [LossIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.lossintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_loss_num(self, obj):
        from django.db.models import Sum
        total = obj.lossintermediatedetailmodel_set.aggregate(
            total=Sum('loss_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_loss_num.short_description = "总报损数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.LossIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报损单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class SurplusIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.SurplusIntermediateDetailModel
        fields = ('raw', 'surplus_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SurplusIntermediateDetailInline(admin.TabularInline):
    model = models.SurplusIntermediateDetailModel
    form = SurplusIntermediateDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "报溢明细"
    verbose_name_plural = "报溢明细"

    # 明细表单字段配置
    fields = ('raw', 'surplus_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields




# 1. 自定义入库单表单，添加校验逻辑
class SurplusIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.SurplusIntermediateOrderModel

        fields = ['orderId', 'date']


# @admin.register(models.SurplusRawDetailModel)
class SurplusIntermediateDetailModelAdmin(admin.ModelAdmin):
    """报溢明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'surplus_num', 'raw_standard', 'create_at','view_details_link')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'surplus_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('surplus_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_surplusintermediateordermodel_change', args=[obj.surplus_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.surplus_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报溢单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SurplusIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报溢单明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)
        # 使用外键字段名+_id 作为筛选参数
        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/search/store/storeintermediatedetailmodel/subledger/?pk={}" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )
    view_details_link.short_description = "明细账"
@admin.register(models.SurplusIntermediateOrderModel)
class SurplusIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SurplusIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_surplus_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SurplusIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.surplusintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_surplus_num(self, obj):
        from django.db.models import Sum
        total = obj.surplusintermediatedetailmodel_set.aggregate(
            total=Sum('surplus_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_surplus_num.short_description = "总报溢数量"
    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SurplusIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报溢单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class SellIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellIntermediateDetailModel
        fields = ('raw', 'sell_num')

# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellIntermediateDetailInline(admin.TabularInline):
    model = models.SellIntermediateDetailModel
    form = SellIntermediateDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "销售明细"
    verbose_name_plural = "销售明细"

    # 明细表单字段配置
    fields = ('raw', 'sell_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class SellIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellIntermediateOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellIntermediateOrderModel)
class SellIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_sell_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_sell_num(self, obj):
        from django.db.models import Sum
        total = obj.sellintermediatedetailmodel_set.aggregate(
            total=Sum('sell_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_sell_num.short_description = "总销售数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.SellRawDetailModel)
class SellIntermediateDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sell_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sell_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sell_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellintermediateordermodel_change', args=[obj.sell_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sell_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False


    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OutboundIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundIntermediateDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundIntermediateDetailInline(admin.TabularInline):
    model = models.OutboundIntermediateDetailModel
    form = OutboundIntermediateDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundIntermediateOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundIntermediateOrderModel)
class OutboundIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundintermediatedetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundIntermediateDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundintermediateordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class OtherOutboundIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundIntermediateDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OtherOutboundIntermediateDetailInline(admin.TabularInline):
    model = models.OtherOutboundIntermediateDetailModel
    form = OtherOutboundIntermediateDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OtherOutboundIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundIntermediateOrderModel

        fields = ['orderId', 'date',]


@admin.register(models.OtherOutboundIntermediateOrderModel)
class OtherOutboundIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OtherOutboundIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OtherOutboundIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.otheroutboundintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.otheroutboundintermediatedetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OtherOutboundIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
@admin.register(models.OtherOutboundIntermediateDetailModel)
class OtherOutboundIntermediateDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_otheroutboundintermediateordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OtherOutboundIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class BackIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackIntermediateDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackIntermediateDetailInline(admin.TabularInline):
    model = models.BackIntermediateDetailModel
    form = BackIntermediateDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackIntermediateOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackIntermediateOrderModel)
class BackIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backintermediatedetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.BackRawDetailModel)
class BackIntermediateDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backintermediateordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OutboundIntermediateOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundIntermediateOfIntermediateProductDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundIntermediateOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.OutboundIntermediateOfIntermediateProductDetailModel
    form = OutboundIntermediateOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundIntermediateOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundIntermediateOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundIntermediateOfIntermediateProductOrderModel)
class OutboundIntermediateOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundIntermediateOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundIntermediateOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundintermediateofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundintermediateofintermediateproductdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundIntermediateOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundIntermediateOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundintermediateofintermediateproductordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundIntermediateOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class BackIntermediateOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackIntermediateOfIntermediateProductDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackIntermediateOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.BackIntermediateOfIntermediateProductDetailModel
    form = BackIntermediateOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackIntermediateOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackIntermediateOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackIntermediateOfIntermediateProductOrderModel)
class BackIntermediateOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackIntermediateOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackIntermediateOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backintermediateofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backintermediateofintermediateproductdetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackIntermediateOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.BackRawDetailModel)
class BackIntermediateOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backintermediateofintermediateproductordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackIntermediateOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions



class SellBackIntermediateDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellBackIntermediateDetailModel
        fields = ('raw', 'sellback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellBackIntermediateDetailInline(admin.TabularInline):
    model = models.SellBackIntermediateDetailModel
    form = SellBackIntermediateDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "销售退货明细"
    verbose_name_plural = "销售退货明细"

    # 明细表单字段配置
    fields = ('raw', 'sellback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class SellBackIntermediateOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellBackIntermediateOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellBackIntermediateOrderModel)
class SellBackIntermediateOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellBackIntermediateOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellBackIntermediateDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellbackintermediatedetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.sellbackintermediatedetailmodel_set.aggregate(
            total=Sum('sellback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退货数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellBackIntermediateOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售退货单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.SellBackRawDetailModel)
class SellBackIntermediateDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sellback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sellback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sellback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellbackintermediateordermodel_change', args=[obj.sellback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sellback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售退货单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellBackIntermediateDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售退货明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions





class StoreFinishedDetailForm(forms.ModelForm):
    # 新增金额字段（不存入数据库，仅用于计算）
    amount = forms.DecimalField(
        label="不含税金额",
        required=False,
        max_digits=12,
        decimal_places=2,
        widget=forms.NumberInput(attrs={
            'class': 'amount-input',  # 用于JS选择
            'step': '0.01'  # 支持小数输入
        })
    )
    class Meta:
        model = models.StoreFinishedDetailModel
        fields = ('raw', 'store_num','unit')

class StoreFinishedOrderFileForm(forms.ModelForm):
    class Meta:
        model = models.StoreFinishedOrderFileModel
        fields = ('id', 'store_order','file')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreFinishedFileInline(admin.TabularInline):
    model = models.StoreFinishedOrderFileModel
    form = StoreFinishedOrderFileForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    classes = ['collapse'] # 添加collapse类，这是Django Admin内置的
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "附件"
    verbose_name_plural = "附件"

    # 明细表单字段配置
    fields = ('file',)


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ()  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题

# 明细项内嵌编辑（在入库单页面直接管理明细）
class StoreFinishedDetailInline(admin.TabularInline):
    model = models.StoreFinishedDetailModel
    form = StoreFinishedDetailForm  # 应用自定义表单
    # template = 'admin/edit_inline/tabular.html'  # 关键：加载我们定制的模板
    # template = 'admin/edit_inline/custom_tabular.html'  # 加载自定义模板
    template = 'store/custom_tabular.html'  # 加载自定义模板
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "入库明细"
    verbose_name_plural = "入库明细"

    # 明细表单字段配置
    fields = ('raw', 'store_num', 'unit', 'price','tax','amount', 'batch_number','location')


    # readonly_fields = ('raw_name',)  # 创建时间只读

    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw','unit')  # 依赖base.RawModel的Admin配置了search_fields
    # fieldsets = (
    #     # 用 fieldsets 将多个字段横向排列，模拟表格的“列”布局
    #     (None, {
    #         'fields': ('raw', 'store_num', 'unit', 'batch_number'),  # 一行显示4个字段
    #         'classes': ('wide', 'extrapretty'),  # 'wide' 让字段横向扩展，减少换行
    #     }),
    # )
    # # 自定义列表字段：显示原料的执行标准
    # def raw_name(self, obj):
    #     return obj.raw.name  if obj.raw else "" # 显示执行标准名称
    # raw_name.short_description = "原料名称"  # 表格中显示的列标题
    def get_queryset(self, request):
        """
        重写查询集：只返回当前入库单关联的、且parent字段为空的明细数据
        - 父类的get_queryset已自动过滤出当前入库单（store_order=当前主表对象）的数据
        - 额外添加parent__isnull=True，过滤掉parent有数值的记录
        """
        qs = super().get_queryset(request)
        # 核心过滤条件：parent为空（parent__isnull=True）
        return qs.filter(parent__isnull=True)
# 1. 自定义入库单表单，添加校验逻辑
class StoreFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.StoreFinishedOrderModel

        fields=['orderId', 'date','type','supplier']



@admin.register(models.StoreFinishedOrderModel)
class StoreFinishedOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = StoreFinishedOrderForm

    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_store_num','type', 'create_at','view_details_link')

    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId','supplier__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('supplier',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [StoreFinishedDetailInline,StoreFinishedFileInline]

    # 表单字段分组
    fieldsets = (
        ('入库单基本信息', {
            'fields': ('orderId', 'date','type','supplier','remark'),
            'description': '请输入入库单号和入库日期'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request, object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """


        parms = {
            'orderId': request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'type': request.POST.get('type'),
            # 'invoice': request.POST.get('invoice'),
            'supplier': request.POST.get('supplier'),
            # 'supplier_name': baseModels.SupplierAdditiveModel.objects.filter(
            #     pk=request.POST.get('supplier', 0)).first().name
        }
        _fileds = []
        details_counts = request.POST.get('storefinisheddetailmodel_set-TOTAL_FORMS','0')

        for i in range(int(details_counts)):
            raw = baseModels.FinishedModel.objects.filter(
                pk=request.POST.get(f'storefinisheddetailmodel_set-{i}-raw')).first(),
            unit = baseModels.UnitModel.objects.filter(
                pk=request.POST.get(f'storefinisheddetailmodel_set-{i}-unit')).first(),
            _fileds.append({
                'id': request.POST.get(f'storefinisheddetailmodel_set-{i}-id'),
                'store_order': request.POST.get(f'storefinisheddetailmodel_set-{i}-store_order'),
                'name': raw[0].name,
                'gui_ge': raw[0].gui_ge,
                'code': raw[0].code,
                'chan_di': raw[0].chan_di,
                'remark': raw[0].remark,
                'standard': str(raw[0].standard.name),
                'storage_condition': raw[0].storage_condition,

                'store_num': request.POST.get(f'storefinisheddetailmodel_set-{i}-store_num'),
                'unit': unit[0].unit,
                'price': request.POST.get(f'storefinisheddetailmodel_set-{i}-price'),
                'tax': request.POST.get(f'storefinisheddetailmodel_set-{i}-tax'),
                'amount': request.POST.get(f'storefinisheddetailmodel_set-{i}-amount'),
                'batch_number': request.POST.get(f'storefinisheddetailmodel_set-{i}-batch_number'),
                'location': request.POST.get(f'storefinisheddetailmodel_set-{i}-location'),

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
            'model': code,
            'parms': parms,
            'report_type': '0',
            'fileds': _fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.storefinisheddetailmodel_set.filter(parent__isnull=True).count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_store_num(self, obj):
        from django.db.models import Sum
        total = obj.storefinisheddetailmodel_set.filter(parent__isnull=True).aggregate(
            total=Sum('store_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_store_num.short_description = "总入库数量"

    # 自定义字段：生成跳转链接（查看明细详情）
    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)

        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/admin/store/storefinisheddetailmodel/?store_order_id={}&parent__isnull=True" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )

    view_details_link.short_description = "操作"  # 表头名称





@admin.register(models.StoreFinishedDetailModel)
class StoreFinishedDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'store_order_link', 'raw','batch_number', 'store_num','unit','remaining_num', 'raw_standard', 'create_at','view_details_link','location','get_type')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'store_order__orderId',  # 关联入库单号
        'raw__name', 'raw__code'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__standard',  # 按执行标准筛选
        'raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('store_order', 'raw','unit')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def store_order_link(self, obj):
        #通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_storefinishedordermodel_change', args=[obj.store_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.store_order.orderId  # 显示入库单号
        )

    store_order_link.short_description = "入库单号"
    store_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def view_details_link(self, obj):
        # 1. 跳转到当前订单的 Admin 详情页（内部链接）
        # admin_url = reverse('admin:store_storerawordermodel_change', args=[obj.id])
        # return format_html('<a href="{}" class="button">查看详情</a>', admin_url)
        # 使用外键字段名+_id 作为筛选参数
        # 2. 跳转到关联的明细列表（假设明细有单独的 Admin 页面）
        return format_html(
            '<a href="/search/store/storefinisheddetailmodel/subledger/?pk={}" target="_blank">查看明细</a>',
            obj.id  # 传递当前订单ID作为筛选条件
        )
    view_details_link.short_description = "明细账"

    # 自定义列表字段：显示原料的入库类型
    def get_type(self, obj):
        if obj.parent:
            return '调拨'
        elif obj.store_order.type == '1':
            return '入库单'
        else:
            return '期初入库单'

    get_type.short_description = "类型"
    # 动态控制列表显示字段（无权限时移除 view_details_link）
    def get_list_display(self, request):
        # 获取默认的列表字段（原 list_display）
        default_list_display = list(self.list_display)  # 原 list_display 是元组，转列表便于修改

        # 检查权限：无权限则移除 "view_details_link" 字段
        if not request.user.has_perm("store.view_subledger_storefinisheddetailmodel"):
            if "view_details_link" in default_list_display:
                default_list_display.remove("view_details_link")

        return default_list_display

class TransferFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.TransferFinishedDetailModel
        fields = ('from_store_detail', 'to_location', 'transfer_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class TransferFinishedDetailInline(admin.TabularInline):
    model = models.TransferFinishedDetailModel
    form = TransferFinishedDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "调拨明细"
    verbose_name_plural = "调拨明细"

    # 明细表单字段配置
    fields = ('from_store_detail', 'transfer_num', 'to_location')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('from_store_detail',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class TransferFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.TransferFinishedOrderModel

        fields = ['orderId', 'date']


@admin.register(models.TransferFinishedOrderModel)
class TransferFinishedOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = TransferFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('orderId',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [TransferFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.transferfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.transferfinisheddetailmodel_set.aggregate(
            total=Sum('transfer_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总调拨数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.TransferFinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的调拨单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


@admin.register(models.TransferFinishedDetailModel)
class TransferFinishedDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'transfer_order_link', 'from_store_detail', 'transfer_num',  'to_location',  'to_store_detail')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'transfer_order__orderId',  # 关联入库单号
        'from_store_detail__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'from_store_detail__raw__standard',  # 按执行标准筛选
        'from_store_detail__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('transfer_order', 'from_store_detail')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def transfer_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_transferfinishedordermodel_change', args=[obj.transfer_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.transfer_order.orderId  # 显示入库单号
        )

    transfer_order_link.short_description = "调拨单号"
    transfer_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.TransferFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的调拨明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的调拨明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class LossFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.LossFinishedDetailModel
        fields = ('raw', 'loss_num')
# 明细项内嵌编辑（在入库单页面直接管理明细）
class LossFinishedDetailInline(admin.TabularInline):
    model = models.LossFinishedDetailModel
    form = LossFinishedDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    verbose_name = "报损明细"
    verbose_name_plural = "报损明细"

    # 明细表单字段配置
    fields = ('raw', 'loss_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class LossFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.LossFinishedOrderModel

        fields = ['orderId', 'date']


@admin.register(models.LossRawDetailModel)
class LossFinishedDetailModelAdmin(admin.ModelAdmin):
    """报损明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'loss_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'loss_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('loss_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_lossfinishedordermodel_change', args=[obj.loss_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.loss_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报损单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.LossFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报损明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
@admin.register(models.LossFinishedOrderModel)
class LossFinishedOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = LossFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_loss_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [LossFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date','remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request, object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """


        parms = {
            'orderId': request.POST.get('orderId'),
            'date': request.POST.get('date'),
            'remark': request.POST.get('remark',''),

        }
        _fileds = []
        details_counts = request.POST.get('lossfinisheddetailmodel_set-TOTAL_FORMS','0')

        for i in range(int(details_counts)):
            raw = models.StoreFinishedDetailModel.objects.filter(
                pk=request.POST.get(f'lossfinisheddetailmodel_set-{i}-raw')).first(),

            _fileds.append({
                'id': request.POST.get(f'lossfinisheddetailmodel_set-{i}-id'),
                'loss_order': request.POST.get(f'lossfinisheddetailmodel_set-{i}-loss_order'),
                'name': raw[0].raw.name,
                'gui_ge': raw[0].raw.gui_ge,
                'code': raw[0].raw.code,
                'chan_di': raw[0].raw.chan_di,
                'remark': raw[0].raw.remark,
                'standard': str(raw[0].raw.standard.name),
                'storage_condition': raw[0].raw.storage_condition,

                'loss_num': request.POST.get(f'lossfinisheddetailmodel_set-{i}-loss_num'),
                'unit': raw[0].unit.unit,
                'price': str(raw[0].price),
                'tax': str(raw[0].tax),
                'amount': str(raw[0].price * raw[0].tax),
                'batch_number': raw[0].batch_number,
                'location': raw[0].location.name,

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
            'model': code,
            'parms': parms,
            'report_type': '0',
            'fileds': _fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.lossfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_loss_num(self, obj):
        from django.db.models import Sum
        total = obj.lossfinisheddetailmodel_set.aggregate(
            total=Sum('loss_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_loss_num.short_description = "总报损数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.LossfinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报损单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报损单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
class SurplusFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.SurplusFinishedDetailModel
        fields = ('raw', 'surplus_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SurplusFinishedDetailInline(admin.TabularInline):
    model = models.SurplusFinishedDetailModel
    form = SurplusFinishedDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "报溢明细"
    verbose_name_plural = "报溢明细"

    # 明细表单字段配置
    fields = ('raw', 'surplus_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields




# 1. 自定义入库单表单，添加校验逻辑
class SurplusFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.SurplusFinishedOrderModel

        fields = ['orderId', 'date']


# @admin.register(models.SurplusRawDetailModel)
class SurplusFinishedDetailModelAdmin(admin.ModelAdmin):
    """报溢明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'surplus_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'surplus_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('surplus_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_surplusfinishedordermodel_change', args=[obj.surplus_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.surplus_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "报溢单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False
    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SurplusFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的报溢单明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

@admin.register(models.SurplusFinishedOrderModel)
class SurplusFinishedOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SurplusFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_surplus_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId',)
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SurplusFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.surplusfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_surplus_num(self, obj):
        from django.db.models import Sum
        total = obj.surplusfinisheddetailmodel_set.aggregate(
            total=Sum('surplus_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_surplus_num.short_description = "总报溢数量"
    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SurplusFinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的报溢单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的报溢单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class SellFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellFinishedDetailModel
        fields = ('raw', 'sell_num')

# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellFinishedDetailInline(admin.TabularInline):
    model = models.SellFinishedDetailModel
    form = SellFinishedDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    verbose_name = "销售明细"
    verbose_name_plural = "销售明细"

    # 明细表单字段配置
    fields = ('raw', 'sell_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields



# 1. 自定义入库单表单，添加校验逻辑
class SellFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellFinishedOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellFinishedOrderModel)
class SellFinishedOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = SellFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_sell_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_sell_num(self, obj):
        from django.db.models import Sum
        total = obj.sellfinisheddetailmodel_set.aggregate(
            total=Sum('sell_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_sell_num.short_description = "总销售数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellFinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
@admin.register(models.SellRawDetailModel)
class SellFinishedDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sell_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sell_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sell_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellfinishedordermodel_change', args=[obj.sell_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sell_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False


    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class OutboundFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundFinishedDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundFinishedDetailInline(admin.TabularInline):
    model = models.OutboundFinishedDetailModel
    form = OutboundFinishedDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundFinishedOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundFinishedOrderModel)
class OutboundFinishedOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundfinisheddetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundFinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundFinishedDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundfinishedordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class OtherOutboundFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundFinishedDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OtherOutboundFinishedDetailInline(admin.TabularInline):
    model = models.OtherOutboundFinishedDetailModel
    form = OtherOutboundFinishedDetailForm  # 应用自定义表单
    extra = 0  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OtherOutboundFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.OtherOutboundFinishedOrderModel

        fields = ['orderId', 'date',]


@admin.register(models.OtherOutboundFinishedOrderModel)
class OtherOutboundFinishedOrderModelAdmin(DefineImportExportModelAdmin):
    """入库单主表管理"""
    form = OtherOutboundFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', )
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    # autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OtherOutboundFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'remark'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )
    def print_one_action(self, request,object_id):
        """
        Handles the default workflow for both the export form and the
        export of data to file.
        """



        # parms=request.GET
        parms ={
            'orderId':request.POST.get('orderId'),
            'date': request.POST.get('date'),

            'remark': request.POST.get('remark'),


        }

        _fileds=[]
        model_label='otheroutboundfinished'
        details_counts=request.POST.get(f'{model_label}detailmodel_set-TOTAL_FORMS',0)

        for i in range(int(details_counts)):
            # raw=baseModels.FinishedModel.objects.filter(pk=request.POST.get(f'{model_label}detailmodel_set-{i}-raw')).first(),
            store_raw=models.StoreFinishedDetailModel.objects.filter(pk=request.POST.get(f'{model_label}detailmodel_set-{i}-raw')).first(),
            raw=store_raw[0].raw


            _fileds.append({
                'id':request.POST.get(f'{model_label}detailmodel_set-{i}-id'),
                'out_order': request.POST.get(f'{model_label}detailmodel_set-{i}-out_order'),
                'name':raw.name,
                'gui_ge': raw.gui_ge,
                'code': raw.code,
                'chan_di': raw.chan_di,
                'remark': raw.remark,
                'standard': str(raw.standard.name),
                'storage_condition': raw.storage_condition,
                'batch_number': store_raw[0].batch_number,
                'location': store_raw[0].location.name,
                'outbound_num': request.POST.get(f'{model_label}detailmodel_set-{i}-outbound_num'),
                'unit': store_raw[0].unit.unit,

            })
        # queryset=self.model.objects.filter(pk=object_id)
        # 获取必要的报表数据
        code = self.model._meta.label
        reports = baseModels.ReportFileModel.objects.filter(
            code=code,
            type='0',
            state='1'
        ).order_by('-default').all()
        context = {
            'objects': [],
            'title': self.model._meta.verbose_name,
            'reports': reports,
             'model': code,
            'parms':parms,
            'report_type':'0',
            'fileds':_fileds
        }
        return render(request, 'admin/print.html', context)
    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.otheroutboundfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.otheroutboundfinisheddetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OtherOutboundFinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
@admin.register(models.OtherOutboundFinishedDetailModel)
class OtherOutboundFinishedDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_otheroutboundfinishedordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染



    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OtherOutboundFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class BackFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackFinishedDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackFinishedDetailInline(admin.TabularInline):
    model = models.BackFinishedDetailModel
    form = BackFinishedDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackFinishedOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackFinishedOrderModel)
class BackFinishedOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backfinisheddetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackFinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.BackRawDetailModel)
class BackFinishedDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backfinishedordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions

class OutboundFinishedOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.OutboundFinishedOfIntermediateProductDetailModel
        fields = ('raw', 'outbound_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class OutboundFinishedOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.OutboundFinishedOfIntermediateProductDetailModel
    form = OutboundFinishedOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num=None # 允许无限添加（默认值，可省略）
    verbose_name = "出库明细"
    verbose_name_plural = "出库明细"

    # 明细表单字段配置
    fields = ('raw', 'outbound_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮

# 1. 自定义入库单表单，添加校验逻辑
class OutboundFinishedOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.OutboundFinishedOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.OutboundFinishedOfIntermediateProductOrderModel)
class OutboundFinishedOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = OutboundFinishedOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_outbound_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [OutboundFinishedOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.outboundfinishedofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_outbound_num(self, obj):
        from django.db.models import Sum
        total = obj.outboundfinishedofintermediateproductdetailmodel_set.aggregate(
            total=Sum('outbound_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_outbound_num.short_description = "总出库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.OutboundFinishedOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的出库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库单（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions
# @admin.register(models.OutboundRawDetailModel)
class OutboundFinishedOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'outbound_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'out_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('out_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_outboundfinishedofintermediateproductordermodel_change', args=[obj.out_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.out_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "出库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.OutboundFinishedOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的出库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的出库明细（并恢复库存）"
        actions['delete_selected'] = (
        custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


class BackFinishedOfIntermediateProductDetailForm(forms.ModelForm):
    class Meta:
        model = models.BackFinishedOfIntermediateProductDetailModel
        fields = ('raw', 'back_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class BackFinishedOfIntermediateProductDetailInline(admin.TabularInline):
    model = models.BackFinishedOfIntermediateProductDetailModel
    form = BackFinishedOfIntermediateProductDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "退库明细"
    verbose_name_plural = "退库明细"

    # 明细表单字段配置
    fields = ('raw', 'back_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class BackFinishedOfIntermediateProductOrderForm(forms.ModelForm):
    class Meta:
        model = models.BackFinishedOfIntermediateProductOrderModel

        fields = ['orderId', 'date', 'product']


@admin.register(models.BackFinishedOfIntermediateProductOrderModel)
class BackFinishedOfIntermediateProductOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = BackFinishedOfIntermediateProductOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'product__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('product',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [BackFinishedOfIntermediateProductDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'product'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.backfinishedofintermediateproductdetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.backfinishedofintermediateproductdetailmodel_set.aggregate(
            total=Sum('back_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退库数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.BackFinishedOfIntermediateProductOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的退库单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.BackRawDetailModel)
class BackFinishedOfIntermediateProductDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'back_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'back_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('back_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_backfinishedofintermediateproductordermodel_change', args=[obj.back_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.back_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "退库单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.BackFinishedOfIntermediateProductDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的退库明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的退库明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions




class SellBackFinishedDetailForm(forms.ModelForm):
    class Meta:
        model = models.SellBackFinishedDetailModel
        fields = ('raw', 'sellback_num')


# 明细项内嵌编辑（在入库单页面直接管理明细）
class SellBackFinishedDetailInline(admin.TabularInline):
    model = models.SellBackFinishedDetailModel
    form = SellBackFinishedDetailForm  # 应用自定义表单
    extra = 1  # 默认显示1行空明细，可动态添加
    max_num = None  # 允许无限添加（默认值，可省略）
    verbose_name = "销售退货明细"
    verbose_name_plural = "销售退货明细"

    # 明细表单字段配置
    fields = ('raw', 'sellback_num')
    # readonly_fields = ('create_at',)  # 创建时间只读
    # 2. 允许删除明细（默认 True，若之前手动设为 False 需改回）
    can_delete = True  # 显式启用删除功能（可选，默认 True，防止被意外禁用）
    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('raw',)  # 依赖base.RawModel的Admin配置了search_fields

    # # 确保没有禁用添加权限（默认返回 True，可省略此方法）
    # def has_add_permission(self, request, obj=None):
    #     # 允许添加明细行（根据业务需求调整条件）
    #     return False  # 关键：返回 True 才会显示"添加另一行"按钮


# 1. 自定义入库单表单，添加校验逻辑
class SellBackFinishedOrderForm(forms.ModelForm):
    class Meta:
        model = models.SellBackFinishedOrderModel

        fields = ['orderId', 'date', 'customer']


@admin.register(models.SellBackFinishedOrderModel)
class SellBackFinishedOrderModelAdmin(admin.ModelAdmin):
    """入库单主表管理"""
    form = SellBackFinishedOrderForm
    # 列表页展示字段
    list_display = ('orderId', 'date', 'detail_count', 'total_back_num', 'create_at')
    # 列表页可点击进入编辑的字段
    list_display_links = ('orderId',)
    # 搜索字段（支持入库单号搜索）
    search_fields = ('orderId', 'customer__name')
    # 外键搜索：通过双下划线指定关联模型的文本字段
    # 'supplier__name',  # 搜索供应商名称（假设SupplierRawModel有name字段）
    # 过滤条件（按日期和创建时间筛选）
    list_filter = ('date', 'create_at')

    # 优化外键选择体验（支持搜索）
    autocomplete_fields = ('customer',)
    # 分页设置
    list_per_page = 10
    # 只读字段
    readonly_fields = ('create_at', 'update_at')

    # 在入库单编辑页嵌入明细项（核心配置）
    inlines = [SellBackFinishedDetailInline]

    # 表单字段分组
    fieldsets = (
        ('基本信息', {
            'fields': ('orderId', 'date', 'customer'),
            'description': '请输入'
        }),
        ('系统记录', {
            'fields': ('create_at', 'update_at'),
            'classes': ('collapse',),  # 可折叠
            'description': '创建和更新时间由系统自动记录，不可修改'
        })
    )

    # 自定义列表字段：显示明细数量
    def detail_count(self, obj):
        return obj.sellbackfinisheddetailmodel_set.count()

    detail_count.short_description = "明细数量"  # 列标题

    # 自定义列表字段：计算总入库数量
    def total_back_num(self, obj):
        from django.db.models import Sum
        total = obj.sellbackfinisheddetailmodel_set.aggregate(
            total=Sum('sellback_num')
        )['total'] or 0
        return f"{total:.2f}"  # 保留两位小数

    total_back_num.short_description = "总退货数量"

    def save_model(self, request, obj, form, change):
        # 保存模型
        super().save_model(request, obj, form, change)



    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用自定义的批量删除方法
                models.SellBackFinishedOrderModel.bulk_delete(queryset)
                modeladmin.message_user(request, "选中的销售退货单已成功删除，相关库存已恢复。")
            except ValidationError as e:
                modeladmin.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货单（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


# @admin.register(models.SellBackRawDetailModel)
class SellBackFinishedDetailModelAdmin(admin.ModelAdmin):
    """入库明细管理（单独查看和筛选）"""

    # 列表页展示字段
    list_display = ('id', 'sell_order_link', 'raw', 'sellback_num', 'raw_standard', 'create_at')
    # 搜索字段（支持入库单号、原料名称、原料代码搜索）
    search_fields = (
        'sellback_order__orderId',  # 关联入库单号
        'raw__raw__name'  # 原料名称和代码
    )
    # 过滤条件
    list_filter = (
        'create_at',
        'raw__raw__standard',  # 按执行标准筛选
        'raw__raw__chan_di'  # 按原料产地筛选
    )
    # 外键支持搜索
    autocomplete_fields = ('sellback_order', 'raw')
    # 只读字段
    readonly_fields = ('create_at', 'update_at')
    # 禁止在列表页直接编辑（避免脱离主单修改）
    list_editable = ()

    # 自定义列表字段：点击入库单号可跳转到主单
    def sell_order_link(self, obj):
        # 通过reverse和模型Admin的URL名称生成链接
        # URL名称格式为：admin:app_label_modelname_change
        url = reverse('admin:store_sellbackfinishedordermodel_change', args=[obj.sellback_order.id])
        return format_html(
            '<a href="{}">{}</a>',
            url,  # 正确生成的URL
            obj.sellback_order.orderId  # 显示入库单号
        )

    sell_order_link.short_description = "销售退货单号"
    sell_order_link.allow_tags = True  # 允许HTML渲染

    # 自定义列表字段：显示原料的执行标准
    def raw_standard(self, obj):
        return obj.raw.raw.standard.name  # 显示执行标准名称

    raw_standard.short_description = "执行标准"

    # 可选：限制只能通过主单添加明细，禁止单独添加
    def has_add_permission(self, request):
        return False

    def get_actions(self, request):
        actions = super().get_actions(request)

        # 替换默认的删除动作
        def custom_delete_selected(modeladmin, request, queryset):
            try:
                # 调用我们自定义的批量删除方法
                models.SellBackFinishedDetailModel.bulk_delete_with_stock_recovery(queryset)
                self.message_user(request, "选中的销售退货明细已成功删除，库存已恢复。")
            except ValidationError as e:
                self.message_user(request, str(e), level='error')

        custom_delete_selected.short_description = "删除选中的销售退货明细（并恢复库存）"
        actions['delete_selected'] = (
            custom_delete_selected, 'delete_selected', custom_delete_selected.short_description)
        return actions


